package com.aricwang.easyprofile.place;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import android.app.Activity;
import android.app.AlertDialog;
import android.app.Dialog;
import android.app.ListActivity;
import android.content.DialogInterface;
import android.content.Intent;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.widget.EditText;
import android.widget.ListView;
import android.widget.SeekBar;
import android.widget.SimpleAdapter;
import android.widget.TextView;
import android.widget.Toast;

import com.aricwang.easyprofile.R;
import com.aricwang.easyprofile.service.ProfileService;

public class PlaceActivity extends ListActivity {
	private static final int DIALOG_WARNING 	= 1;
	private static final int DIALOG_NAME 		= 2;
	private static final int DIALOG_ADDRESS		= 3;
	private static final int DIALOG_RADIUS		= 4;
	
	private int mRequest;
	private String mWarning = new String();

	private Place mPlace;
	
	private SimpleAdapter mAdapter = null;

	/////////////////////////////////////////////////////////////////////////////////////////
	// Static functions 
	/////////////////////////////////////////////////////////////////////////////////////////

	static void startActivity(Activity activity, int request, int placeId, String placeName) {
		Intent intent = new Intent().setClass(activity, PlaceActivity.class);
		intent.putExtra("Request", request);
		intent.putExtra("PlaceId", placeId);
		intent.putExtra("PlaceName", placeName);
		activity.startActivityForResult(intent, request);
	}

	/////////////////////////////////////////////////////////////////////////////////////////
	// Public functions 
	/////////////////////////////////////////////////////////////////////////////////////////
	
	// set the warning string which will be shown by warning dialog
	public void setWarning(int stringId) {
		mWarning = getString(stringId);
	}
	
	// update the ListAdapter with the current data
	public void updateListAdapter() {
		String[] from = new String[]{"title", "info", "more"};
        int to[] = new int[]{R.id.title, R.id.info, R.id.more};
        mAdapter = new SimpleAdapter(this, getData(), 
        		R.layout.place_details_row, from, to);
		
        setListAdapter(mAdapter);
	}


	/////////////////////////////////////////////////////////////////////////////////////////
	// Override functions 
	/////////////////////////////////////////////////////////////////////////////////////////

	public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        initMembers();
        setContentView(R.layout.list_details);
		updateListAdapter();
    }
	
	protected void onActivityResult(int requestCode, int resultCode, Intent data) {
	    super.onActivityResult(requestCode, resultCode, data);
	    
	    if (resultCode != RESULT_OK)
	    	return;
	    
	    if (requestCode == MyMapActivity.REQ_CURRENT_LOCATION 
	    		|| requestCode == MyMapActivity.REQ_SHOW_LOCATION) {
	    	mPlace.mAddress = data.getExtras().getString("Address");
	    	mPlace.mLatitude = data.getExtras().getDouble("Latitude");
	    	mPlace.mLongitude = data.getExtras().getDouble("Longitude");
	    	
	    	updateListAdapter();
	    }
	}
	
	protected void onListItemClick(ListView l, View v, int position, long id) {
		switch(position) {
		case 0:		// Place name edit
			showDialog(DIALOG_NAME);
			break;
		case 1:
			int req;
			if (mPlace.mLatitude == 0 && mPlace.mLongitude == 0)
				req = MyMapActivity.REQ_CURRENT_LOCATION;
			else
				req = MyMapActivity.REQ_SHOW_LOCATION;
		
			MyMapActivity.startActivity(this, req, mPlace.mLatitude, mPlace.mLongitude);
			break;
		case 2:		
			showDialog(DIALOG_ADDRESS);
			break;
		case 3:
			showDialog(DIALOG_RADIUS);
			break;
		default:
			break;
		}
		
		mAdapter.notifyDataSetChanged();
	}
		
	protected Dialog onCreateDialog(int id) {
	    Dialog dialog = null;
        switch(id) {
	    case DIALOG_WARNING:
	    	dialog = createDialogWarning();
	    	break;
	    	
	    case DIALOG_NAME:
            dialog = createDialogName();	
	        break;
	        
	    case DIALOG_ADDRESS:
	    	dialog = createDialogAddress();
	    	break;
	        
	    case DIALOG_RADIUS:
	    	dialog = createDialogRadius();
	    	break;

	    default:
	    	break;
	    }
	    
	    return dialog;
	}

	protected void onPrepareDialog(int id, Dialog dialog) {
	    switch(id) {
	    default:
	    	break;
	    }
	}
	
	/////////////////////////////////////////////////////////////////////////////////////////
	// OnClickListener interface implementation
	// handle the click event of the buttons on this page: save and cancel
	/////////////////////////////////////////////////////////////////////////////////////////
	public void onClick(View v) {
		int id = v.getId();
		
		switch(id) {
		case R.id.btn_save:
			savePlace();
			ProfileService.notifyConfigChanged(this);
			setResult(RESULT_OK);
			break;
		case R.id.btn_cancel:
			setResult(RESULT_CANCELED);
			break;
		default:
			break;
		}
		
		finish();
	}
	
		
	/////////////////////////////////////////////////////////////////////////////////////////
	// Private functions 
	/////////////////////////////////////////////////////////////////////////////////////////
	
	
	private void initMembers() {
        mRequest = PlaceListActivity.REQ_ADD;

        Intent intent = getIntent();
        if (intent == null || intent.getExtras() == null) {
        	return;
        }
        
    	mRequest = intent.getExtras().getInt("Request");

    	switch(mRequest) {
        case PlaceListActivity.REQ_ADD:
        	mPlace = new Place();
        	mPlace.mName = intent.getExtras().getString("PlaceName");
        	break;
       
        case PlaceListActivity.REQ_EDIT:
        case PlaceListActivity.REQ_COPY:
        	int id = intent.getExtras().getInt("PlaceId");
        	
        	mPlace = Place.getPlace(this, id);

			if (mPlace != null && mRequest == PlaceListActivity.REQ_COPY) {
				mPlace.mName = "Copy of " + mPlace.mName;
			}
        	break;
       
        default:
        	break;
        }
	}
	
	// a helper function for getData
	private void addDataToList(List<Map<String, Object>>list, String title, String info) {
		if (list == null)
			return;
		
		Map<String, Object> map;

		map = new HashMap<String, Object>();
        map.put("title", title);
        map.put("info", info);
        map.put("more", android.R.drawable.ic_menu_more);
        
        list.add(map);

        return;
	}
	
	// get profile data from content provider.
	// if request is ProfileListActivity.REQ_ADD_PROFILE, use profileName to create one;
	// if request is ProfileListActivity.REQ_EDIT_PROFILE, use profileId to retrieve the data;
	// TODO: replace the strings here with resouce ids
	private List<Map<String, Object>> getData() {
		List<Map<String, Object>> list = new ArrayList<Map<String, Object>>();
		
		if (mPlace != null) {
			// list position: 0, Place name
			addDataToList(list, "Place Name", mPlace.mName);
			
			// list position: 1, location (latitude/longitude)
			addDataToList(list, "Location", 
					"Latitude: " + mPlace.mLatitude + ", Longitude: " + mPlace.mLongitude
					+ "\n(Tap icon on right to show it on the map, or search by address).");

			// list position: 2, address
			addDataToList(list, "Address", mPlace.mAddress);
			
			// list position: 3, radius
			addDataToList(list, "Radius", "" + mPlace.mRadius + " meters");
		}
		
        return list;
	}

	// save the Place data to database
	private void savePlace() {
		if (mRequest == PlaceListActivity.REQ_EDIT) {
			// for edit, update the existing record
			Place.updatePlace(this, mPlace);
		} else {
			// for add or copy, insert the new record
			Place.insertPlace(this, mPlace);
		}
	}

	// dialog warning creator
	private Dialog createDialogWarning() {
        AlertDialog.Builder builder = new AlertDialog.Builder(this);
        
        builder.setMessage(mWarning)
            .setPositiveButton(R.string.ok, new DialogInterface.OnClickListener() {
                public void onClick(DialogInterface dialog, int whichButton) {
                	dialog.dismiss();
                }
            });
        
        return builder.create();
	}

	// dialog name creator
	private Dialog createDialogName() {
        AlertDialog.Builder builder = new AlertDialog.Builder(this);

        LayoutInflater factory = LayoutInflater.from(this);
        View dialogView = factory.inflate(R.layout.dialog_edit_text, null);
        final EditText editText = (EditText)dialogView.findViewById(R.id.edit_text);
        editText.setText(mPlace.mName);
        
        builder.setTitle(R.string.place_name)
            .setView(dialogView)
            .setPositiveButton(R.string.ok, new DialogInterface.OnClickListener() {
                public void onClick(DialogInterface dialog, int whichButton) {
                	String name = editText.getText().toString();
                	
                	if (name.length() <= 0) {
                    	// if name is empty, warn user
                		PlaceActivity.this.setWarning(R.string.warning_place_name_empty);
                		PlaceActivity.this.showDialog(PlaceActivity.DIALOG_WARNING);
                	} else {
            			// save the profile name
                		mPlace.mName = name;
                		updateListAdapter();
                	}

                	dialog.dismiss();
                }
            })
            .setNegativeButton(R.string.cancel, new DialogInterface.OnClickListener() {
                public void onClick(DialogInterface dialog, int whichButton) {
                	dialog.cancel();
                }
            });
        
        return builder.create();	
	}

	// dialog address creator
	private Dialog createDialogAddress() {
        AlertDialog.Builder builder = new AlertDialog.Builder(this);

        LayoutInflater factory = LayoutInflater.from(this);
        View dialogView = factory.inflate(R.layout.dialog_edit_text, null);
        final EditText editText = (EditText)dialogView.findViewById(R.id.edit_text);
        editText.setText(mPlace.mAddress);
        
        builder.setTitle(R.string.address)
            .setView(dialogView)
            .setPositiveButton(R.string.ok, new DialogInterface.OnClickListener() {
                public void onClick(DialogInterface dialog, int whichButton) {
                	String text = editText.getText().toString();
                	
                	if (text.length() <= 0) {
                    	// if name is empty, warn user
                		PlaceActivity.this.setWarning(R.string.warning_address_empty);
                		PlaceActivity.this.showDialog(PlaceActivity.DIALOG_WARNING);
                	} else {
            			// save the profile name
                		mPlace.mAddress = text;
                		updateListAdapter();
                	}

                	dialog.dismiss();
                }
            })
            .setNegativeButton(R.string.cancel, new DialogInterface.OnClickListener() {
                public void onClick(DialogInterface dialog, int whichButton) {
                	dialog.cancel();
                }
            });
        
        return builder.create();	
	}

	private Dialog createDialogRadius() {
        AlertDialog.Builder builder = new AlertDialog.Builder(this);
        
        LayoutInflater factory = LayoutInflater.from(this);
        View dialogView = factory.inflate(R.layout.dialog_radius, null);
        
        final SeekBar seekBar = (SeekBar)dialogView.findViewById(R.id.seek_bar_radius);
        seekBar.setMax(Place.RADIUS_MAX);
        seekBar.setProgress(mPlace.mRadius);
        
        final TextView label = (TextView)dialogView.findViewById(R.id.label_radius);
        label.setText("" + mPlace.mRadius + " meters");
        
        seekBar.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
    	    public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
    	    	label.setText("" + progress + " meters");
    	    }

    	    public void onStartTrackingTouch(SeekBar seekBar) {
    	    }
    	    
    	    public void onStopTrackingTouch(SeekBar seekBar) {
    	    }
        });

        builder.setTitle(R.string.radius)
        .setView(dialogView)
        .setPositiveButton(R.string.ok, new DialogInterface.OnClickListener() {
            public void onClick(DialogInterface dialog, int whichButton) {
            	mPlace.mRadius = seekBar.getProgress();
           		updateListAdapter();
            	dialog.dismiss();
            }
        })
        .setNegativeButton(R.string.cancel, new DialogInterface.OnClickListener() {
            public void onClick(DialogInterface dialog, int whichButton) {
            	dialog.cancel();
            }
        });

        return builder.create();
    }

	/////////////////////////////////////////////////////////////////////////////////////////
	// Inner classes
	/////////////////////////////////////////////////////////////////////////////////////////


}
